package com.seedwill.common.util;

import java.util.HashMap;
import java.util.Map;

import ognl.OgnlException;

/**
 * @author kdyi
 *
 * TODO 增加cache Object expression = ognl.Ognl.parseExpression(propName); 
 */
public class OgnlHelper {
	
public static final String defaultParaToken = ";";
	

	private static boolean enableCache = false;
	/**
	 * 评估参数值
	 * 参数使用OGNL表达式
	 * @param context
	 * @param initClauseCtxPara
	 * @return
	 */
	public static Object[] evalContextParas(Object context, String initClauseCtxPara) {
		return evalContextParas(context, initClauseCtxPara, defaultParaToken);
	}
	
	/**
	 * 评估参数值
	 * 参数使用OGNL表达式
	 * @param context
	 * @param initClauseCtxPara
	 * @param token
	 * @return
	 */
	public static Object[] evalContextParas(Object context, String initClauseCtxPara, String token) {
		Object[] paras = null;
		if(null != initClauseCtxPara && initClauseCtxPara.length()>0){
			String[] paraNames = initClauseCtxPara.split(token);
			paras = new Object[paraNames.length];
			for(int i=0; i<paraNames.length; i++){
				paras[i] = evalContextPara(context, paraNames[i]);
			}
		}
		return paras;
	}
	
	/**
	 * 评估参数值
	 * 参数使用OGNL表达式
	 * @param context
	 * @param paraName
	 * @return
	 */
	public static Object evalContextPara(Object context, String paraName) {
		Object paraValue = null;
		if(null != paraName && paraName.length()>0){
			try {
				Object expression = ognl.Ognl.parseExpression(paraName); 
				paraValue = ognl.Ognl.getValue(expression, context);
			} catch (OgnlException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return paraValue;
	}
	
	private static Map<String, Object> cache = java.util.Collections.synchronizedMap(new HashMap<String,Object>(32, 0.75f));
	
	
	
	
	public static Object evalValue(Object host, String propName) {
		Object value = null;
		try {
			Object expression = null;
			String key = genStoreKey(host, propName);
			if(enableCache){
				if(cache.containsKey(key)){
					expression = cache.containsKey(propName); 
				}else{
					expression = ognl.Ognl.parseExpression(propName); 
					cache.put(key, expression);
				}
			}else{
				expression = ognl.Ognl.parseExpression(propName); 
			}

			if(null != expression){
				value = ognl.Ognl.getValue(expression, host);
			}else{
				throw new RuntimeException(" invliad expression null for " + propName);
			}
		} catch (OgnlException e) {
			e.printStackTrace();
		}
		return value;
	}
	
	
	public static Object evalValueDirectly(Object host, String propName) {
		Object value = null;
		try {
			Object expression = ognl.Ognl.parseExpression(propName); 
			if(null != expression){
				value = ognl.Ognl.getValue(expression, host);
			}else{
				throw new RuntimeException(" invliad expression null for " + propName);
			}
		} catch (OgnlException e) {
			e.printStackTrace();
		}
		return value;
	}
	
	private static String genStoreKey(Object host, String propName) {
		return null != host ? host.getClass().getName()+"$"+propName : "NULL$"+propName;
	}

	public static void pushValue(Object host, String propName, Object value) {
		try {
			Object expression = null;
			String key = genStoreKey(host, propName);
			
			if(enableCache){
				if(cache.containsKey(key)){
					expression = cache.get(key); 
				}else{
					expression = ognl.Ognl.parseExpression(propName); 
					cache.put(key, expression);
				}
			}else{
				expression = ognl.Ognl.parseExpression(propName); 
			}
			if(null != expression){
				ognl.Ognl.setValue(expression, host, value);
			}else{
				throw new RuntimeException(" invliad expression null for " + propName);
			}
			
		} catch (OgnlException e) {
			e.printStackTrace();
		}
	}
	public static void pushValueDirectly(Object host, String propName, Object value) {
		try {
			Object expression = ognl.Ognl.parseExpression(propName); 
			if(null != expression){
				ognl.Ognl.setValue(expression, host, value);
			}else{
				throw new RuntimeException(" invliad expression null for " + propName);
			}
			
		} catch (OgnlException e) {
			e.printStackTrace();
		}
	}
	
//	public static void main(String[] args){
//		
//		 Demo demo = new  Demo();
//		 demo.setName("小狗");
//		 demo.setAge(12);
//		 
//		 System.out.println(OgnlHelper.evalValue(demo, "name"));
//		 System.out.println(OgnlHelper.evalValue(demo, "name"));
//		 System.out.println(OgnlHelper.evalValue(demo, "name"));
//		 System.out.println(OgnlHelper.evalValue(demo, "name"));
//		 Object val = OgnlHelper.evalValue(demo, "age");
//		 System.out.println(val + ", type:"+val.getClass().getName());
//		
//		
//	}
}
